package com.gxa.hualianeshop.common.util;

import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.interfaces.DecodedJWT;

import java.util.Date;

/**
 * @author bill
 * @version 1.0
 * @date 2020/10/12 0012 10:15
 */
public class JwtUtil {

    //JWT验证过期时间 EXPIRE_TIME(单位:毫秒) , 指定为30分钟
    //private static final long EXPIRE_TIME = 30 * 60 * 1000;

    // 60秒钟用于测试
   // private static final long EXPIRE_TIME = 600*1000;

    // 签发方法,生成Jwt
    public static String sign(String claimName, String value ,long expire ) {
        // 设置jwt的过期时间
        Date date = new Date(System.currentTimeMillis() + expire);

        //普通管理员和超级管理员验证手机号,采用手机号后六位加密生成私钥
        Algorithm algorithm = Algorithm.HMAC256(value.substring(5));

        //生成jwt: 带有用指定密钥进行加密, 对主体进行加密并设定过期时间
        String auth = JWT.create()
                .withClaim(claimName, value)
                .withExpiresAt(date)
                .sign(algorithm);
        return auth;
    }

    public static boolean isExpire(String token){
        DecodedJWT decode = JWT.decode(token);
        Date expiresAt = decode.getExpiresAt();
        // 比较token过期时间和当前系统时间的大小
        // 比目标值大返回1, 比目标值小返回-1 , 相等返回0
        int i = expiresAt.compareTo(new Date());
        return i<0;
    }

    /**
     * 获得token中的信息无需secret解密也可直接获取
     * @return jwt中声明的手机号
     */
    public static String getClaim(String token,String claimName) {
        // 从token中解密得到jwt中的载荷信息
        // 得到一个可以读取jwt中的信息的调用对象:DecodedJWT
        DecodedJWT jwt = JWT.decode(token);
        return jwt.getClaim(claimName).asString();
    }

    /**
     * 校验jwt是否正确
     * @param token  需要校验的jwt字符串
     * @return 返回验证结果
     */
    public static boolean verify(String token,String claimName, String claimValue) {
        try {
            //根据密码生成JWT私钥校验器
            // 普通管理员和超级管理员,都采用手机号后六位加密
            Algorithm algorithm =  Algorithm.HMAC256(claimValue.substring(5));

            //校验环节
            // 生成一个校验器
            JWTVerifier verifier = JWT.require(algorithm)
                    .withClaim(claimName, claimValue)
                    .build();

            //校验JWT: 通过异常来确定是否校验成功
            DecodedJWT decodedJWT = verifier.verify(token);
            // 测试一下jwt验证后生成的状态
            // System.out.println(decodedJWT);
            return true;
        } catch (Exception exception) {
            return false;
        }
    }
}